package com.richard.base.common

import android.annotation.SuppressLint
import android.app.Activity
import android.app.ActivityManager
import android.content.Context
import android.net.ConnectivityManager
import android.os.Process
import java.util.*
import kotlin.system.exitProcess

/**
 ***************************************
 * 项目名称:Giggle
 * @Author wuzhiguo
 * 邮箱：wuzhiguo@ksjgs.com
 * 创建时间: 2020/7/14     4:08 PM
 * 用途:
 ***************************************
 */


/**
 * 判断设备是否安装微信APP
 *
 * @return boolean
 */
fun Context.isWeixinAvilible(): Boolean {
    val pinfo = packageManager.getInstalledPackages(0)// 获取所有已安装程序的包信息
    if (pinfo != null) {
        for (i in pinfo.indices) {
            val pn = pinfo[i].packageName
            if ("com.tencent.mm" == pn) {
                return true
            }
        }
    }
    return false
}


/**
 * 是否有网络连接
 * @receiver Context
 * @return Boolean
 */
@SuppressLint("MissingPermission")
fun Context.isNetworkAvailable(): Boolean {
    val mNetworkInfo = connectivityManager?.activeNetworkInfo
    return mNetworkInfo != null && mNetworkInfo.isAvailable
}


/**
 * 检测网络是否是Mobile
 *
 * @return
 */
fun Context.isMobile(): Boolean {
    val mNetworkInfo = connectivityManager?.activeNetworkInfo
    return mNetworkInfo != null
            && mNetworkInfo.type == ConnectivityManager.TYPE_MOBILE
            && mNetworkInfo.isConnected
}

/**
 * 判断wifi是否连接
 *
 * @return
 */
fun Context.isWifiConnected(): Boolean {
    val activeNetInfo = connectivityManager?.activeNetworkInfo
    return activeNetInfo != null
            && activeNetInfo.type == ConnectivityManager.TYPE_WIFI
            && activeNetInfo.isConnected
}

/**
 * 是否有运行的服务
 * @receiver Context
 * @param className String
 * @return Boolean
 */
fun Context.isServiceRunning(className: String): Boolean {
    var isRunning = false
    val serviceList = activityManager?.getRunningServices(Int.MAX_VALUE)
    if (serviceList == null || serviceList.size <= 0) {
        return false
    }
    for (i in serviceList.indices) {
        if (serviceList[i] != null && serviceList[i].service != null) {
            val cName = serviceList[i].service.className
            if (cName.contains(className)) {
                isRunning = true
                break
            }
        }
    }
    return isRunning
}
/**
 * 包名判断是否为主进程
 *
 * @param context
 * @return
 */
fun Context.isMainProcess(): Boolean {
    return packageName == getProcessName()
}

/**
 * 获取进程名称
 *
 * @param context
 * @return
 */
fun Context.getProcessName(): String? {
    try {
        val runningApps = activityManager?.runningAppProcesses ?: return null
        for (proInfo in runningApps) {
            if (proInfo.pid == Process.myPid()) {
                if (proInfo.processName != null) {
                    return proInfo.processName
                }
            }
        }
    } catch (e: Exception) {
        e.printStackTrace()
    }
    return null
}

/**
 * 判断当前app是否存活
 * @receiver Context
 * @param packageName String
 * @return Boolean
 */
fun Context.isAppAlive(packageName: String): Boolean {
    val processInfos = activityManager?.runningAppProcesses
    if (processInfos != null) {
        for (i in processInfos.indices) {
            if (processInfos[i].processName == packageName) {
                return true
            }
        }
    }
    return false
}

/**
 * 清楚当前所有的activity
 */
fun Context.clearAllActivity() {
    val allActivitys = getAllActivitys()
    for (i in allActivitys.indices) {
        allActivitys.get(i).finish()
    }
}

/**
 * 获取当前所有的activity
 *
 * @return activity列表
 */
@SuppressLint("PrivateApi", "DiscouragedPrivateApi")
fun Context.getAllActivitys(): List<Activity> {
    val list = ArrayList<Activity>()
    try {
        val activityThread = Class.forName("android.app.ActivityThread")
        val currentActivityThread = activityThread.getDeclaredMethod("currentActivityThread")
        currentActivityThread.isAccessible = true
        //获取主线程对象
        val activityThreadObject = currentActivityThread.invoke(null)
        val mActivitiesField = activityThread.getDeclaredField("mActivities")
        mActivitiesField.isAccessible = true
        val mActivities = mActivitiesField.get(activityThreadObject) as Map<Any, Any>
        for ((_, value) in mActivities) {
            val activityClientRecordClass = value.javaClass
            val activityField = activityClientRecordClass.getDeclaredField("activity")
            activityField.isAccessible = true
            val o = activityField.get(value)
            list.add(o as Activity)
        }
    } catch (e: Exception) {
        e.printStackTrace()
    }

    return list
}

/**
 * 注意：不能先杀掉主进程，否则逻辑代码无法继续执行，需先杀掉相关进程最后杀掉主进程
 */
fun Context.killAppProcess() {
    val mList = activityManager?.runningAppProcesses
    for (runningAppProcessInfo in mList!!) {
        if (runningAppProcessInfo.pid != Process.myPid()) {
            Process.killProcess(runningAppProcessInfo.pid)
        }
    }
    Process.killProcess(Process.myPid())
    exitProcess(0)
}



/**
 * 开启一个service之前需要判断是否开启
 * @receiver Context
 * @param className String
 * @param action Function0<Unit>
 */
fun Context.onServiceNotRunning(className: String, action: () -> Unit) {
    try {
        if (isAppInForground()) {
            val downloadPetServiceRunning: Boolean = isServiceRunning(className)
            if (!downloadPetServiceRunning) {
                action()
            }
        }
    } catch (e: IllegalStateException) {
        e.printStackTrace()
    } catch (e: SecurityException) {
        e.printStackTrace()
    }
}

/**
 * 判断app是否在前台
 * @receiver Context
 * @return Boolean
 */
fun Context.isAppInForground(): Boolean {
    val processes = activityManager?.runningAppProcesses ?: return false
    for (tmp in processes) {
        if (tmp.processName == this.packageName) {
            return tmp.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND
        }
    }
    return false
}